home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / science / ack3d.zip / ACKDOOR.C < prev    next >
Text File  |  1994-01-09  |  10KB  |  396 lines

  1. /******************* ( Animation Construction Kit 3D ) ***********************/
  2. /*                 Door Routines                     */
  3. /*  CopyRight (c) 1993       Author: Lary Myers                     */
  4. /*****************************************************************************/
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <dos.h>
  9. #include <mem.h>
  10. #include <alloc.h>
  11. #include <io.h>
  12. #include <fcntl.h>
  13. #include <time.h>
  14. #include <string.h>
  15. #include <sys\stat.h>
  16. #include "ack3d.h"
  17. #include "ackeng.h"
  18. #include "ackext.h"
  19.  
  20. /****************************************************************************
  21. ** Check all the doors to see what state they are in. If a door's column   **
  22. ** offset is non-zero then it is either opening or closing, so add in the  **
  23. ** speed of the door and check for fully open and fully closed conditions. **
  24. **                                       **
  25. **                                       **
  26. ****************************************************************************/
  27. void CheckDoors(ACKENG *ae)
  28. {
  29.      int    i,MapPosn,mPos,mPos1;
  30.      int    column,mx,my,DeltaGrid;
  31.      int    xPlayer,yPlayer;
  32. unsigned char    mCode,mCode1;
  33.  
  34. xPlayer = ae->xPlayer;
  35. yPlayer = ae->yPlayer;
  36.  
  37. for (i = 0; i < MAX_DOORS; i++)
  38.     {
  39.     if (ae->Door[i].ColOffset)
  40.     {
  41.     ae->Door[i].ColOffset += ae->Door[i].Speed;
  42.     mPos = ae->Door[i].mPos;
  43.     mPos1 = ae->Door[i].mPos1;
  44.  
  45.    /* Door is closing and is visible. Put old codes back to make non-passable */
  46.     if (ae->Door[i].Speed < 0 && ae->Door[i].ColOffset < 65)
  47.         {
  48.         MapPosn = (yPlayer & 0xFFC0) + (xPlayer >> 6);
  49.         if (MapPosn == mPos ||
  50.         MapPosn == mPos1)
  51.         {
  52.         ae->Door[i].ColOffset -= ae->Door[i].Speed;
  53.         continue;
  54.         }
  55.  
  56.         if (ae->Door[i].Type == DOOR_XCODE)
  57.         {
  58.         ae->xGrid[mPos]     = ae->Door[i].mCode;
  59.         ae->xGrid[mPos1] = ae->Door[i].mCode1;
  60.         }
  61.         else
  62.         {
  63.         ae->yGrid[mPos]     = ae->Door[i].mCode;
  64.         ae->yGrid[mPos1] = ae->Door[i].mCode1;
  65.         }
  66.  
  67. /* Door is close enough to fully closed to get rid of the door from the array */
  68.         if (ae->Door[i].ColOffset < 3)
  69.         {
  70.         ae->Door[i].ColOffset = 0;
  71.         ae->Door[i].mPos      = -1;
  72.         ae->Door[i].mPos1     = -1;
  73.         ae->Door[i].Flags     = 0;
  74.         }
  75.  
  76.         }
  77.  
  78.     /* Door is fully open, reverse the speed to begin closing */
  79.     if (ae->Door[i].ColOffset > 0xA0)
  80.         {
  81.         ae->Door[i].Speed = -ae->Door[i].Speed;
  82.         ae->Door[i].Flags &= ~DOOR_OPENING;
  83.         ae->Door[i].Flags |= DOOR_CLOSING;
  84.         }
  85.  
  86.     }
  87.     }
  88.  
  89.  
  90. /* Now check for any action occuring in a secret door. This is currently  */
  91. /* setup to handle only one door at a time in the X and Y directions, but */
  92. /* it should be fairly straightforward to use a list of doors, similiar      */
  93. /* to normal doors, to handle more than one.                  */
  94. if (xSecretColumn)
  95.     {
  96.     if (xSecretColumn > 0)        /* See if the door is to the right of us */
  97.     {
  98.     mPos = xSecretmPos1;
  99.     DeltaGrid = -1;
  100.     xSecretColumn += ae->DoorSpeed;
  101.     }
  102.     else
  103.     {
  104.     mPos = xSecretmPos;
  105.     DeltaGrid = 0;
  106.     xSecretColumn -= ae->DoorSpeed;
  107.     }
  108.  
  109.     my = mPos & 0xFFC0;
  110.     mx = (mPos - my) << 6;
  111.  
  112.     if (abs(xSecretColumn) > GRID_SIZE)        /* Beyond one grid square */
  113.     {
  114.     mx += xSecretColumn;
  115.     my = my + (mx >> 6);
  116.     if (ae->xGrid[my])            /* No further, an obstruction */
  117.         {
  118.         ae->xGrid[xSecretmPos] = 0;
  119.         ae->xGrid[xSecretmPos1] = 0;
  120.         my += DeltaGrid;
  121.         ae->xGrid[my] = ae->NonSecretCode;
  122.         ae->xGrid[my+1] = ae->NonSecretCode;
  123.         ae->yGrid[my] = ae->NonSecretCode;
  124.         ae->yGrid[my + GRID_WIDTH] = ae->NonSecretCode;
  125.         xSecretColumn = 0;
  126.         }
  127.     else
  128.         {
  129.         if (my != mPos)
  130.         {
  131.         ae->xGrid[xSecretmPos] = 0;
  132.         ae->xGrid[xSecretmPos1] = 0;
  133.         if (xSecretColumn > 0)
  134.             {
  135.             xSecretColumn -= 63;
  136.             ae->xGrid[my] = DOOR_TYPE_SECRET + 1;
  137.             xSecretmPos1 = my;
  138.             my--;
  139.             ae->xGrid[my] = DOOR_TYPE_SECRET + 1;
  140.             xSecretmPos = my;
  141.             }
  142.         else
  143.             {
  144.             xSecretColumn += 63;
  145.             ae->xGrid[my] = DOOR_TYPE_SECRET + 1;
  146.             ae->xGrid[my+1] = DOOR_TYPE_SECRET + 1;
  147.             xSecretmPos = my;
  148.             xSecretmPos = my+1;
  149.             }
  150.         }
  151.         } /* End if (xGrid[my]) ... else ...     */
  152.     }     /* End if (abs(xSecretColumn) > GRID_SIZE) */
  153.     }          /* End if (xSecretColumn)             */
  154.  
  155. /* Perform same process on a secret door that may be moving in the Y */
  156. /* direction. The same door can move either way, depending on which  */
  157. /* angle the player struck it at.                     */
  158. if (ySecretColumn)
  159.     {
  160.     if (ySecretColumn > 0)
  161.     {
  162.     mPos = ySecretmPos1;
  163.     DeltaGrid = -GRID_WIDTH;
  164.     ySecretColumn += ae->DoorSpeed;
  165.     }
  166.     else
  167.     {
  168.     mPos = ySecretmPos;
  169.     DeltaGrid = 0;
  170.     ySecretColumn -= ae->DoorSpeed;
  171.     }
  172.  
  173.     my = mPos & 0xFFC0;
  174.     mx = (mPos - my) << 6;
  175.  
  176.     if (abs(ySecretColumn) > GRID_SIZE)
  177.     {
  178.     my += ySecretColumn;
  179.     my = (my & 0xFFC0) + (mx >> 6);
  180.     if (ae->yGrid[my])
  181.         {
  182.         ae->yGrid[ySecretmPos] = 0;
  183.         ae->yGrid[ySecretmPos1] = 0;
  184.         my += DeltaGrid;
  185.         ae->xGrid[my] = ae->NonSecretCode;
  186.         ae->xGrid[my+1] = ae->NonSecretCode;
  187.         ae->yGrid[my] = ae->NonSecretCode;
  188.         ae->yGrid[my + GRID_WIDTH] = ae->NonSecretCode;
  189.         ySecretColumn = 0;
  190.         }
  191.     else
  192.         {
  193.         if (my != mPos)
  194.         {
  195.         ae->yGrid[ySecretmPos] = 0;
  196.         ae->yGrid[ySecretmPos1] = 0;
  197.         if (ySecretColumn > 0)
  198.             {
  199.             ySecretColumn -= 63;
  200.             ae->yGrid[my] = DOOR_TYPE_SECRET + 1;
  201.             ySecretmPos1 = my;
  202.             my -= GRID_WIDTH;
  203.             ae->yGrid[my] = DOOR_TYPE_SECRET + 1;
  204.             ySecretmPos = my;
  205.             }
  206.         else
  207.             {
  208.             ySecretColumn += 63;
  209.             ae->yGrid[my] = DOOR_TYPE_SECRET + 1;
  210.             ae->yGrid[my+GRID_WIDTH] = DOOR_TYPE_SECRET + 1;
  211.             ySecretmPos = my;
  212.             ySecretmPos = my+GRID_WIDTH;
  213.             }
  214.         }
  215.         }
  216.     }
  217.     }
  218.  
  219. }
  220.  
  221. /****************************************************************************
  222. ** Locate a door from its Map coordinate and return the index to the       **
  223. ** caller.                                   **
  224. **                                       **
  225. ****************************************************************************/
  226. int FindDoor(int MapPosn,ACKENG *ae)
  227. {
  228.     int        index;
  229.  
  230. for (index = 0; index < MAX_DOORS; index++)
  231.     {
  232.     if (MapPosn == ae->Door[index].mPos || MapPosn == ae->Door[index].mPos1)
  233.     return(index);
  234.     }
  235.  
  236. return(-1);
  237. }
  238.  
  239.  
  240. /****************************************************************************
  241. ** Find an empty slot for a door. If the door already occupies a slot and  **
  242. ** it is in a non-closed state then return error.               **
  243. **                                       **
  244. ****************************************************************************/
  245. int FindDoorSlot(int MapPosn,ACKENG *ae)
  246. {
  247.     int        index;
  248.  
  249. index = FindDoor(MapPosn,ae);
  250. if (index >= 0 && ae->Door[index].ColOffset)
  251.     return(-1);
  252.  
  253. for (index = 0; index < MAX_DOORS; index++)
  254.     {
  255.     if (ae->Door[index].mPos == -1)
  256.     return(index);
  257.  
  258.     }
  259.  
  260. return(-1);
  261. }
  262.  
  263. /****************************************************************************
  264. ** The application performs this call to see if the POV is close enough to **
  265. ** a door to begin opening it. (A good time to make this call would be       **
  266. ** when the POV moves). If a door is activated a return code tells the       **
  267. ** application what kind of door it was (for purposes of sound, etc.)       **
  268. **                                       **
  269. ****************************************************************************/
  270. int AckCheckDoorOpen(int xPlayer,int yPlayer,int PlayerAngle,ACKENG *ae)
  271. {
  272.     int        i,j,DoorCode;
  273.  
  274. DoorCode = POV_NODOOR;        /* Default - assumes no doors found */
  275.  
  276. i = AckCheckHit(xPlayer,yPlayer,PlayerAngle,ae);
  277.  
  278. /* Check secret doors along the X walls */
  279. if (i == 1 && ae->xGrid[xMapPosn] & DOOR_TYPE_SECRET)
  280.     {
  281.     if (xSecretColumn == 0)
  282.     {
  283.     DoorCode = POV_XSECRETDOOR;
  284.  
  285.     if (ae->xGrid[xMapPosn] & DOOR_LOCKED)
  286.         return(DoorCode | POV_DOORLOCKED);
  287.  
  288.     xSecretmPos = xMapPosn;
  289.     if (iLastX > xPlayer)
  290.         {
  291.         xSecretmPos1 = xMapPosn + 1;
  292.         LastMapPosn = xMapPosn;
  293.         xSecretColumn = 1;
  294.         ae->yGrid[xMapPosn] = ae->yGrid[xMapPosn - GRID_WIDTH];
  295.         }
  296.     else
  297.         {
  298.         LastMapPosn = xSecretmPos1 = xMapPosn - 1;
  299.         xSecretColumn = -1;
  300.         ae->yGrid[xSecretmPos1] = ae->yGrid[xSecretmPos1 - GRID_WIDTH];
  301.         }
  302.     }
  303.  
  304.     }
  305.  
  306. /* Check secret doors along the Y walls */
  307. if (i == 2 && ae->yGrid[yMapPosn] & DOOR_TYPE_SECRET)
  308.     {
  309.     if (ySecretColumn == 0)
  310.     {
  311.     DoorCode = POV_YSECRETDOOR;
  312.  
  313.     if (ae->yGrid[yMapPosn] & DOOR_LOCKED)
  314.         return(DoorCode | POV_DOORLOCKED);
  315.  
  316.     ySecretmPos = yMapPosn;
  317.     if (iLastY > yPlayer)
  318.         {
  319.         LastMapPosn = yMapPosn;
  320.         ySecretmPos1 = yMapPosn + GRID_WIDTH;
  321.         ae->xGrid[yMapPosn] = ae->xGrid[yMapPosn-1];
  322.         ySecretColumn = 1;
  323.         }
  324.     else
  325.         {
  326.         LastMapPosn = ySecretmPos1 = yMapPosn - GRID_WIDTH;
  327.         ae->xGrid[ySecretmPos1] = ae->xGrid[ySecretmPos1 - 1];
  328.         ySecretColumn = -1;
  329.         }
  330.     }
  331.     }
  332.  
  333. /* Check doors along the X walls */
  334. if (i == 1 && (ae->xGrid[xMapPosn] & 0xFF) == DOOR_XCODE)
  335.     {
  336.     j = FindDoorSlot(xMapPosn,ae);
  337.     if (j >= 0)
  338.     {
  339.     DoorCode = POV_XDOOR;
  340.  
  341.     LastMapPosn = ae->Door[j].mPos = xMapPosn;
  342.     if ((int)iLastX > xPlayer)
  343.         i = xMapPosn + 1;
  344.     else
  345.         LastMapPosn = i = xMapPosn - 1;
  346.  
  347.     if (ae->xGrid[xMapPosn] & DOOR_LOCKED)
  348.         {
  349.         ae->Door[j].mPos = -1;
  350.         return(DoorCode | POV_DOORLOCKED);
  351.         }
  352.  
  353.     ae->Door[j].mCode = ae->xGrid[xMapPosn];
  354.     ae->Door[j].mCode1 = ae->xGrid[i];
  355.     ae->Door[j].mPos1 = i;
  356.     ae->Door[j].ColOffset = 1;
  357.     ae->Door[j].Speed = ae->DoorSpeed;
  358.     ae->Door[j].Type = DOOR_XCODE;
  359.     ae->Door[j].Flags = DOOR_OPENING;
  360.     }
  361.     }
  362.  
  363. /* Check doors along the Y walls */
  364. if (i == 2 && (ae->yGrid[yMapPosn] & 0xFF) == DOOR_YCODE)
  365.     {
  366.     j = FindDoorSlot(yMapPosn,ae);
  367.     if (j >= 0)
  368.     {
  369.     DoorCode = POV_YDOOR;
  370.     LastMapPosn = ae->Door[j].mPos = yMapPosn;
  371.     if ((int)iLastY > yPlayer)
  372.         i = yMapPosn + GRID_WIDTH;
  373.     else
  374.         LastMapPosn = i = yMapPosn - GRID_WIDTH;
  375.  
  376.     if (ae->yGrid[yMapPosn] & DOOR_LOCKED)
  377.         {
  378.         ae->Door[j].mPos = -1;
  379.         return(DoorCode | POV_DOORLOCKED);
  380.         }
  381.  
  382.     ae->Door[j].mCode = ae->yGrid[yMapPosn];
  383.     ae->Door[j].mCode1 = ae->yGrid[i];
  384.     ae->Door[j].mPos1 = i;
  385.     ae->Door[j].ColOffset = 1;
  386.     ae->Door[j].Speed = ae->DoorSpeed;
  387.     ae->Door[j].Type = DOOR_YCODE;
  388.     ae->Door[j].Flags = DOOR_OPENING;
  389.     }
  390.     }
  391.  
  392. return(DoorCode);
  393. }
  394.  
  395.  
  396.